package com.infore.qualityControl.util;

import com.infore.qualityControl.enums.QualityDataRevisonEnum;
import com.infore.qualityControl.enums.QualityProjectEnum;

/**
 * 质控数据计算方法工具类
 * @author Cold
 *
 */
public class QualityDataUtil {
	
	public static final String DATA_FLAG = "-"; 
	
	// 测试
	public static void main(String[] args) {
		// 加标回收率
		String eDouble = standardRecoveryRate(1.8, 1.8, 0.0, 200.0, 40.0);
		System.out.println(eDouble);
		String fDouble = integratedInterventionRelativeError(1.43, 1.46);
		System.out.println(fDouble);
		String gDouble = realWaterSampleComparisonError(1.43, 1.35, "w21001");
		System.out.println(gDouble);
	}
	
	/**
	* @Title: zeroCheckAbsoluteError
	* @Description: 计算24小时零点核查绝对误差
	* @param zeroValue  仪器零点测定值
	* @param standardValue  标准溶液浓度值
	* @param indexCode  监测编码
	* @return    参数
	* @return Double    返回类型
	* @throws
	 */
	public static String zeroCheckAbsoluteError(Double zeroValue, Double standardValue, String indexCode) {
		Double value = zeroValue - standardValue;
		String error = "0";
		if (indexCode.equals(QualityProjectEnum.IMN.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_IMN.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.NH3.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_NH3.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.TP.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_TP.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.TN.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_TN.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.PH.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_PH.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.WT.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_WT.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.DO.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_DO.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.EC.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_EC.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.TUB.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_TUB.getDigit());
		}
		return error;
	}
	/**
	* @Title: zeroDriftRelativeError
	* @Description: 计算24小时零点漂移相对误差
	* @param nowZeroValue  当日仪器零点测定值
	* @param lastDayZeroValue  前一日仪器零点测定值
	* @param spanValue  仪器跨度值
	* @param indexCode  监测编码
	* @return    参数
	* @return Double    返回类型
	* @throws
	 */
	public static String zeroDriftRelativeError(Double nowZeroValue, Double lastDayZeroValue, Double spanValue) {
		if (nowZeroValue == lastDayZeroValue) {
			return DATA_FLAG;
		}
		return ScaleUtil.sciCalSix(((nowZeroValue - lastDayZeroValue) * 100 / spanValue),
				QualityDataRevisonEnum.RELATIVE_ERROR.getDigit());
	}
	/**
	* @Title: spanCheckAbsoluteError
	* @Description: 计算24小时跨度核查相对误差
	* @param spanValue  仪器测定值
	* @param standardValue  标准溶液浓度值
	* @param indexCode  监测编码
	* @return    参数
	* @return Double    返回类型
	* @throws
	 */
	public static String spanCheckRelativeError(Double spanValue, Double standardValue, String indexCode) {
		if (spanValue == standardValue) {
			return DATA_FLAG;
		}
		return ScaleUtil.sciCalSix(((spanValue - standardValue) * 100 / standardValue),
				QualityDataRevisonEnum.RELATIVE_ERROR.getDigit());
	}
	/**
	* @Title: spanDriftRelativeError
	* @Description: 计算24小时跨度漂移相对误差
	* @param nowSpanValue  当日仪器测定值
	* @param lastDaySpanValue  前一日仪器测定值
	* @param spanValue  仪器跨度值
	* @return    参数
	* @return Double    返回类型
	* @throws
	 */
	public static String spanDriftRelativeError(Double nowSpanValue, Double lastDaySpanValue, Double spanValue) {
		if (nowSpanValue == lastDaySpanValue) {
			return DATA_FLAG;
		}
		return ScaleUtil.sciCalSix(((nowSpanValue - lastDaySpanValue) * 100 / spanValue),
				QualityDataRevisonEnum.RELATIVE_ERROR.getDigit());
	}
	/**
	* @Title: MultipointCorrelationCoefficient
	* @Description: 计算多点线性的相关系数
	* @param x  X轴数据
	* @param y  Y轴数据
	* @return    参数
	* @return Double    返回类型
	* @throws
	 */
	public static String MultipointCorrelationCoefficient(double[] x, double[] y) {
		return ScaleUtil.sciCalSix(new LeastSquareMethodUtil().lineRegression(x, y),
				QualityDataRevisonEnum.CORRELATION_COEFFICIENT.getDigit());
	}
	/**
	* @Title: standardRecoveryRate
	* @Description: 计算加标回收率
	* @param addValue  加标后水样测定值
	* @param sampleValue  样品测定值
	* @param addVolume  加标体积
	* @param addConcentration  加标样浓度
	* @param waterSampleVolume  加标后水样体积
	* @return    参数
	* @return Double    返回类型
	* @throws
	 */
	public static String standardRecoveryRate(Double addValue, Double sampleValue, Double addVolume,
			Double addConcentration, Double waterSampleVolume) {
		if (addValue == sampleValue) { // 相等情况下,计算公式分子为0,无法计算
			return DATA_FLAG;
		}
		return ScaleUtil.sciCalSix((addValue - sampleValue) * 100 / (addVolume * addConcentration / waterSampleVolume),
				QualityDataRevisonEnum.STANDARD_RECOVERY_RATE.getDigit());
	}
	/**
	* @Title: integratedInterventionRelativeError
	* @Description: 计算集成干预相对误差
	* @param automaticValue  系统自动测试值
	* @param manualValue  人工采样测试值
	* @return    参数
	* @return Double    返回类型
	* @throws
	 */
	public static String integratedInterventionRelativeError(Double automaticValue, Double manualValue) {
		if (manualValue == automaticValue || (manualValue + automaticValue) == 0) { // 相等情况下,计算公式分子为0,无法计算
			return DATA_FLAG;
		}
		return ScaleUtil.sciCalSix(
				(Math.abs(manualValue - automaticValue) * 100 / ((manualValue + automaticValue) / 2)),
				QualityDataRevisonEnum.INTEGRATED_INTERVENTION.getDigit());
	}
	/**
	* @Title: realWaterSampleComparisonError
	* @Description: 计算实际水样对比误差值
	* @param automaticValue  系统自动测试值
	* @param manualValue  人工采样测试值
	* @return    参数
	* @return Double    返回类型
	* @throws
	 */
	public static String realWaterSampleComparisonError(Double automaticValue, Double manualValue, String indexCode) {
		Double value = automaticValue - manualValue;
		String error = "0";
		// 水温、PH、溶解氧是计算绝对误差,其余是计算相对误差
		if (indexCode.equals(QualityProjectEnum.WT.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_WT.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.PH.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_PH.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.DO.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_DO.getDigit());
		} else {
			if (value == 0 || manualValue == 0) {
				return DATA_FLAG;
			}
			value = (automaticValue - manualValue) / manualValue;
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.RELATIVE_ERROR.getDigit());
		}
		return error;
	}
	
	/**
	* @Title: verificationOfStandardSamplesError
	* @Description: 计算标样核查误差值
	* @param value  测定值
	* @param standardValue  标准值
	* @return    参数
	* @return String    返回类型
	* @throws
	 */
	public static String verificationOfStandardSamplesError(Double checkValue, Double standardValue, String indexCode) {
		// PH、温度、溶解氧按绝对误差(这里是水温)
		// 电导率、浊度按相对误差
		// 高锰酸盐、氨氮、总磷、总氮按绝对误差
		Double value = checkValue - standardValue;
		String error = "0";
		if (indexCode.equals(QualityProjectEnum.WT.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_WT.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.PH.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_PH.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.DO.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_DO.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.IMN.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_IMN.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.NH3.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_NH3.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.TP.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_TP.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.TN.getCode())) {
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_TN.getDigit());
		} else {
			if (value == 0 || standardValue == 0) {
				return DATA_FLAG;
			}
			value = (checkValue - standardValue) / standardValue;
			error = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.RELATIVE_ERROR.getDigit());
		}
		return error;
	}
	
	/** 质控内的数据修约 **/
	// 暂时用绝对误差的修约数
	public static Double scaleData(String indexCode, Double value) {
		String scaleValue = "0";
		if (indexCode.equals(QualityProjectEnum.IMN.getCode())) {
			scaleValue = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_IMN.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.NH3.getCode())) {
			scaleValue = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_NH3.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.TP.getCode())) {
			scaleValue = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_TP.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.TN.getCode())) {
			scaleValue = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_TN.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.WT.getCode())) {
			scaleValue = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_WT.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.PH.getCode())) {
			scaleValue = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_PH.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.DO.getCode())) {
			scaleValue = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_DO.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.EC.getCode())) {
			scaleValue = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_EC.getDigit());
		} else if (indexCode.equals(QualityProjectEnum.TUB.getCode())) {
			scaleValue = ScaleUtil.sciCalSix(value, QualityDataRevisonEnum.ABSOLUTE_ERROR_TUB.getDigit());
		}
		return Double.valueOf(scaleValue);
	}
}
